package top.byteio.common.core.utils;

import cn.hutool.captcha.LineCaptcha;
import cn.hutool.core.bean.BeanUtil;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 通用工具
 *
 * @author lerryxia
 * @since 2023/6/21 1:23
 */
public final class CommonUtils {

    private static final Pattern linePattern = Pattern.compile("_(\\w)");

    private static final Pattern humpPattern = Pattern.compile("[A-Z]");

    /**
     * 生成图形验证码
     *
     * @param codeCount 验证码长度
     * @return cn.hutool.captcha.LineCaptcha
     * @author lerryxia
     * @since 2023/7/11 12:43
     */
    public static LineCaptcha Captcha(int codeCount) {
        return new LineCaptcha(100, 100, codeCount, 4);
    }


    /**
     * 字符串首字母转小写
     *
     * @param s 字符串
     * @return java.lang.String
     * @author lerryxia
     * @since 2023/7/8 15:29
     */
    public static String toLowerCaseFirstOne(String s) {
        if (Character.isLowerCase(s.charAt(0))) {
            return s;
        } else {
            return Character.toLowerCase(s.charAt(0)) + s.substring(1);
        }
    }

    /**
     * 将下划线转驼峰
     *
     * @param str 字符串
     * @return java.lang.String
     * @author lerryxia
     * @since 2023/7/9 22:43
     */
    public static String underlineToHump(String str) {
        Matcher m = linePattern.matcher(str);
        StringBuilder sb = new StringBuilder();
        while (m.find()) {
            m.appendReplacement(sb, m.group(1).toUpperCase());
        }
        m.appendTail(sb);
        return sb.toString();
    }

    /**
     * 驼峰转下划线
     *
     * @param str 字符串
     * @return java.lang.String
     * @author lerryxia
     * @since 2023/7/9 22:47
     */
    public static String humpToUnderline(String str) {
        String charAt = String.valueOf(str.charAt(0));
        Matcher m = humpPattern.matcher(str);
        StringBuilder sb = new StringBuilder();
        while (m.find()) {
            m.appendReplacement(sb, "_" + m.group(0).toLowerCase());
        }
        m.appendTail(sb);
        String string = sb.toString();
        return string.replace("_" + string.charAt(1), charAt);
    }

    /**
     * 使用真实文件名生成唯一文件名
     * <br>格式： rand_date_yyyyMMddHHmmss_filename_Filename;
     * rand：四位数随机数字，yyyyMMddHHmmss：此格式的日期  ；Filename：文件原名称
     *
     * @param filename 真实文件名
     * @return 唯一文件名
     * @author lerryxia
     */
    public static String generateUniqueFilename(String filename) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String timestamp = sdf.format(new Date());
        Random random = new Random();
        int rand = random.nextInt(10000);
        return rand + "_date_" + timestamp + "_filename_" + filename;
    }

    /**
     * @param uniqueFilename 唯一文件名
     * @return java.lang.String 真实文件名
     * @author lerryxia
     */
    public static String restoreFilename(String uniqueFilename) {
        int indexOf = uniqueFilename.indexOf("_filename_");
        if (indexOf != -1) {
            return uniqueFilename.substring(indexOf + 10);
        }
        return uniqueFilename;
    }

    /**
     * 通过文件名获取文件类型(文件拓展名)
     *
     * @param fileName 文件名
     * @return java.lang.String
     * @author lerryxia
     * 2023/4/25 23:15
     */
    public static String getFileType(String fileName) {
        int dotIndex = fileName.lastIndexOf(".");
        if (dotIndex != -1 && dotIndex < fileName.length() - 1) {
            return fileName.substring(dotIndex + 1);
        } else {
            return "";
        }
    }


    /**
     * 生成随机字符串(一般是生成验证码)
     * <br>ASCII代码 48～57为0到九十个阿拉伯数字。
     * <br> 65～90为26个大写英文字母，97～122号为26个小写英文字母
     *
     * @param length     长度
     * @param isAlphabet 是否包含英文字母
     * @return char[]
     * @author lerryxia
     * 2023/5/2 16:29
     */
    public static char[] generateRandomCharacters(int length, boolean isAlphabet) {
        Random random = new Random();
        char[] captcha = new char[length];
        if (isAlphabet) {
            for (int i = 0; i < length; i++) {
                int anInt = random.nextInt(3);
                switch (anInt) {
                    case 0 -> captcha[i] = (char) (random.nextInt(26) + 65);
                    case 1 -> captcha[i] = (char) (random.nextInt(26) + 97);
                    case 2 -> captcha[i] = (char) (random.nextInt(10) + 48);
                    default -> {
                    }
                }
            }
        } else {
            for (int i = 0; i < length; i++) {
                int nextInt = random.nextInt(10) + 48;
                captcha[i] = (char) nextInt;
            }
        }
        return captcha;
    }

    /**
     * JavaBean属性复制工具，可以将一个JavaBean对象的属性值拷贝到另一个JavaBean对象中，
     * 并支持类型转换、映射配置等高级功能。
     *
     * @param sourceObject 源javabean对象
     * @param targetClazz  目标java对象
     * @return T
     * @author lerryxia
     */
    public static <T> T convertClass(Object sourceObject, Class<T> targetClazz) {
        String[] ignore = new String[0];
        return BeanUtil.copyProperties(sourceObject, targetClazz, ignore);
    }


}
